/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010

    This file is part of Maxsi Engine.

    Maxsi Engine is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi Engine is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi Engine. If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiEngineContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiEngineContributors.h. For more information please see
	MaxsiEngineContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]

	MaxsiEngine.dll
	A linkable version of Maxsi Engine

	MaxsiComplex.cpp
	IMAGINARY FUNCTIONS!

****************************************************************************/

#include "MaxsiEngine.h"

namespace MaxsiEngine
{
	#define A (Real)
	#define B (Imaginary)
	#define C (Oprand.Real)
	#define D (Oprand.Imaginary)

	ComplexDouble::ComplexDouble()
	{
		A		=	0.0f;
		B		=	0.0f;
	}

	ComplexDouble::ComplexDouble(double Reality)
	{
		A		=	Reality;
		B		=	0.0f;
	}

	ComplexDouble::ComplexDouble(double Reality, double Imagination)
	{
		A		=	Reality;
		B		=	Imagination;
	}

	bool	ComplexDouble::operator==	(const ComplexDouble& Oprand)
	{
		return (Real == Oprand.Real) && (Imaginary == Oprand.Imaginary);
	}

	bool	ComplexDouble::operator!=	(const ComplexDouble& Oprand)
	{
		return (Real != Oprand.Real) || (Imaginary != Oprand.Imaginary);		
	}


	ComplexDouble&		ComplexDouble::operator=	(const ComplexDouble& Oprand)
	{
		A		=	C;
		B		=	D;
		return (*this);
	}

	ComplexDouble&		ComplexDouble::operator-=	(const ComplexDouble& Oprand)
	{
		A		-=	C;
		B		-=	D;
		return (*this);
	}

	ComplexDouble&		ComplexDouble::operator+=	(const ComplexDouble& Oprand)
	{
		A		+=	C;
		B		+=	D;
		return (*this);
	}

	ComplexDouble&		ComplexDouble::operator*=	(const ComplexDouble& Oprand)
	{
		// (A+Bi)*(C+Di) = AC+ADi+CBi+BiDi = (AC-BD) + i(AD+BC) where i = Sqrt(-1)

		double	OldA	=	A;
		double	OldC	=	C;

		A		=	(A*C) - (B*D);
		B		=	(OldA*D) + (B*OldC);

		return (*this);
	}

	ComplexDouble&		ComplexDouble::operator/=	(const ComplexDouble& Oprand)
	{
		// (A+Bi)/(C+Di)

		double	OldA	=	A;
		double	OldC	=	C;

		A		=	(A*C+B*D)/(C*C+D*D);
		B		=	(B*C-OldA*D)/(OldC*OldC+D*D);
		return (*this);
	}

	ComplexDouble&		ComplexDouble::operator+	(const ComplexDouble& Oprand)
	{
		A		+=	C;
		B		+=	D;
		return (*this);
	}

	ComplexDouble&		ComplexDouble::operator-	(const ComplexDouble& Oprand)
	{
		A		-=	C;
		B	-=	D;
		return (*this);
	}

	ComplexDouble&		ComplexDouble::operator*	(const ComplexDouble& Oprand)
	{
		// (A+Bi)*(C+Di) = AC+ADi+CBi+BiDi = (AC-BD) + i(AD+BC) where i = Sqrt(-1)

		double	OldA	=	A;
		double	OldC	=	C;

		A		=	(A*C) - (B*D);
		B		=	(OldA*D) + (B*OldC);

		return (*this);
	}

	ComplexDouble&		ComplexDouble::operator/	(const ComplexDouble& Oprand)
	{
		// (A+Bi)/(C+Di)

		double	OldA	=	A;
		double	OldC	=	C;

		A		=	(A*C+B*D)/(C*C+D*D);
		B		=	(B*C-OldA*D)/(OldC*OldC+D*D);
		return (*this);
	}



	ComplexFloat::ComplexFloat()
	{
		A		=	0.0f;
		B		=	0.0f;
	}

	ComplexFloat::ComplexFloat(float Reality)
	{
		A		=	Reality;
		B		=	0.0f;
	}

	ComplexFloat::ComplexFloat(float Reality, float Imagination)
	{
		A		=	Reality;
		B		=	Imagination;
	}

	bool	ComplexFloat::operator==	(const ComplexFloat& Oprand)
	{
		return (Real == Oprand.Real) && (Imaginary == Oprand.Imaginary);
	}

	bool	ComplexFloat::operator!=	(const ComplexFloat& Oprand)
	{
		return (Real != Oprand.Real) || (Imaginary != Oprand.Imaginary);		
	}


	ComplexFloat&		ComplexFloat::operator=	(const ComplexFloat& Oprand)
	{
		A		=	C;
		B		=	D;
		return (*this);
	}

	ComplexFloat&		ComplexFloat::operator-=	(const ComplexFloat& Oprand)
	{
		A		-=	C;
		B		-=	D;
		return (*this);
	}

	ComplexFloat&		ComplexFloat::operator+=	(const ComplexFloat& Oprand)
	{
		A		+=	C;
		B		+=	D;
		return (*this);
	}

	ComplexFloat&		ComplexFloat::operator*=	(const ComplexFloat& Oprand)
	{
		// (A+Bi)*(C+Di) = AC+ADi+CBi+BiDi = (AC-BD) + i(AD+BC) where i = Sqrt(-1)

		float	OldA	=	A;
		float	OldC	=	C;

		A		=	(A*C) - (B*D);
		B		=	(OldA*D) + (B*OldC);

		return (*this);
	}

	ComplexFloat&		ComplexFloat::operator/=	(const ComplexFloat& Oprand)
	{
		// (A+Bi)/(C+Di)

		float	OldA	=	A;
		float	OldC	=	C;

		A		=	(A*C+B*D)/(C*C+D*D);
		B		=	(B*C-OldA*D)/(OldC*OldC+D*D);
		return (*this);
	}

	ComplexFloat&		ComplexFloat::operator+	(const ComplexFloat& Oprand)
	{
		A		+=	C;
		B		+=	D;
		return (*this);
	}

	ComplexFloat&		ComplexFloat::operator-	(const ComplexFloat& Oprand)
	{
		A		-=	C;
		B	-=	D;
		return (*this);
	}

	ComplexFloat&		ComplexFloat::operator*	(const ComplexFloat& Oprand)
	{
		// (A+Bi)*(C+Di) = AC+ADi+CBi+BiDi = (AC-BD) + i(AD+BC) where i = Sqrt(-1)

		float	OldA	=	A;
		float	OldC	=	C;

		A		=	(A*C) - (B*D);
		B		=	(OldA*D) + (B*OldC);

		return (*this);
	}

	ComplexFloat&		ComplexFloat::operator/	(const ComplexFloat& Oprand)
	{
		// (A+Bi)/(C+Di)

		float	OldA	=	A;
		float	OldC	=	C;

		A		=	(A*C+B*D)/(C*C+D*D);
		B		=	(B*C-OldA*D)/(OldC*OldC+D*D);
		return (*this);
	}
}
